package com.waves.core.utils;


import cn.hutool.extra.spring.SpringUtil;
import com.waves.core.config.ThreadPoolConfig;
import com.waves.core.transaction.MultiplyThreadTransactionManager;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.CompletableFuture;

/**
 * 多线程utils
 */
public class CompletableFutureUtils {

    @Qualifier(ThreadPoolConfig.PUBLIC_EXECUTOR)
    private static final ThreadPoolTaskExecutor publicExecutor;

    private static final MultiplyThreadTransactionManager multiplyThreadTransactionManager;

    static {
        publicExecutor = SpringUtil.getBean(ThreadPoolTaskExecutor.class);
        multiplyThreadTransactionManager = SpringUtil.getBean(MultiplyThreadTransactionManager.class);
    }

    /**
     * 异步执行单个任务
     * @param run
     * @return
     */
    public static CompletableFuture<Void> createRun(Runnable run) {
        return CompletableFuture.runAsync(run, publicExecutor).exceptionally(e -> {
            throw new RuntimeException("异步任务出现异常");
        });
    }

    /**
     * 异步执行多个不同的任务
     * @param runs
     * @return
     */
    public static CompletableFuture<Void> createRuns(Runnable... runs) {
        List<CompletableFuture<Void>> completableFutureList = new ArrayList<>();
        for (Runnable run : runs) {
            completableFutureList.add(createRun(run));
        }
        return CompletableFuture.allOf(completableFutureList.toArray(CompletableFuture[]::new));
    }

    /**
     * todo 暂不可用，待完善
     * 适合增删改，可回滚的多线程任务
     * @param runs
     */
    public static void createTransactionRuns(Runnable...runs){
        // true代表出现异常
        if (multiplyThreadTransactionManager.runAsyncButWaitUntilAllDown(Arrays.asList(runs), publicExecutor)) {
            throw new RuntimeException("异步任务出现异常");
        }
    }

}
